﻿#region zh-CHS 2006 - 2010 DemoSoft 团队 | en 2006-2010 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the MMOSE(Massively Multiplayer Online Server Engine) for .NET.
//
//                              2006-2010 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Demo.Mmose.Core.Util;
using System.Threading;
#endregion

namespace Demo.Mmose.Core.Entity.Suit.Quest
{
    /// <summary>
    /// 任务的集合器
    /// </summary>
    public class QuestCollections<QuestT> where QuestT : Quest
    {

        #region zh-CHS 共有属性 | en Public Properties

        #region zh-CHS Owner属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Unit m_Owner;
        #endregion
        /// <summary>
        /// 任务的集合器拥有者
        /// </summary>
        public Unit Owner
        {
            get { return m_Owner; }
            set { m_Owner = value; }
        }

        #endregion

        #region zh-CHS ActiveQuests属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 已经激活的任务
        /// </summary>
        private QuestCollection<QuestT> m_ActiveQuests = new QuestCollection<QuestT>();
        #endregion
        /// <summary>
        /// 已经激活的任务
        /// </summary>
        public QuestCollection<QuestT> ActiveQuests
        {
            get { return m_ActiveQuests; }
        }

        #endregion

        #region zh-CHS FinishQuest属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 已经完成的任务
        /// </summary>
        private QuestCollection<QuestT> m_FinishQuest = new QuestCollection<QuestT>();
        #endregion
        /// <summary>
        /// 已经完成的任务
        /// </summary>
        public QuestCollection<QuestT> FinishQuest
        {
            get { return m_FinishQuest; }
        }

        #endregion

        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        /// <summary>
        /// 完成指定激活的任务（从激活的任务里面）
        /// </summary>
        /// <returns></returns>
        public bool CompleteActivationQuest( long questId )
        {
            QuestT activeQuest = m_ActiveQuests.FindQuestOnId( questId );
            if ( activeQuest == null )
                return false;

            QuestT finishQuest = m_FinishQuest.FindQuestOnId( questId );
            if ( finishQuest != null )
                return false;

            m_FinishQuest.AddQuest( questId, activeQuest );

            return true;
        }

        /// <summary>
        /// 是否是激活的任务
        /// </summary>
        /// <param name="questId"></param>
        /// <returns></returns>
        public bool IsActivationQuest( long questId )
        {
            QuestT activeQuest = m_ActiveQuests.FindQuestOnId( questId );
            if ( activeQuest == null )
                return false;
            else
                return true;
        }

        /// <summary>
        /// 是否是完成的任务
        /// </summary>
        /// <param name="questId"></param>
        /// <returns></returns>
        public bool IsFinishQuest( long questId )
        {
            QuestT finishQuest = m_FinishQuest.FindQuestOnId( questId );
            if ( finishQuest == null )
                return false;
            else
                return true;
        }

        /// <summary>
        /// 是否是有此任务
        /// </summary>
        /// <returns></returns>
        public bool IsHaveThisQuest( long questId )
        {
            if ( IsActivationQuest( questId ) == false )
                return false;

            if ( IsFinishQuest( questId ) == false )
                return false;

            return true;
        }

        /// <summary>
        /// 获取没有拥有的任务
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Quest> ToHaveQuest( QuestCollection<QuestT> questCollection )
        {
            List<QuestT> listQuest = new List<QuestT>( questCollection.Count );

            foreach ( var item in questCollection )
            {
                QuestT activeQuest = m_ActiveQuests.FindQuestOnId( item.Serial );
                if ( activeQuest == null )
                    continue;

                QuestT finishQuest = m_FinishQuest.FindQuestOnId( item.Serial );
                if ( finishQuest == null )
                    continue;

                listQuest.Add( item );
            }

            return listQuest;
        }

        /// <summary>
        /// 获取没有拥有的任务
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Quest> ToNotHaveQuest( QuestCollection<QuestT> questCollection )
        {
            List<Quest> listQuest = new List<Quest>( questCollection.Count );

            foreach ( var item in questCollection )
            {
                QuestT activeQuest = m_ActiveQuests.FindQuestOnId( item.Serial );
                if ( activeQuest != null )
                    continue;

                QuestT finishQuest = m_FinishQuest.FindQuestOnId( item.Serial );
                if ( finishQuest != null )
                    continue;

                listQuest.Add( item );
            }

            return listQuest;
        }

        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private static QuestT[] s_ZeroQuests = new QuestT[0];
        #endregion
        /// <summary>
        /// 获取当前任务容器内所有可以接的任务
        /// </summary>
        /// <returns></returns>
        public IEnumerable<QuestT> ToAvailableQuests( QuestCollection<QuestT> questCollection )
        {
            EventHandler<AvailableQuestsCallEventArgs<QuestCollection<QuestT>, QuestT>> tempEventArgs = m_EventAvailableQuests;
            if ( tempEventArgs != null )
            {
                AvailableQuestsCallEventArgs<QuestCollection<QuestT>, QuestT> eventArgs = new AvailableQuestsCallEventArgs<QuestCollection<QuestT>, QuestT>( questCollection, this );
                tempEventArgs( this, eventArgs );

                return eventArgs.AvailableQuests;
            }

            return s_ZeroQuests; 
        }

        #endregion

        #region zh-CHS 共有事件 | en Public Event

        #region zh-CHS AvailableQuestsCallEventArgs事件 | en Public Event

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<AvailableQuestsCallEventArgs<QuestCollection<QuestT>, QuestT>> m_EventAvailableQuests;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockEventAvailableQuests = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<AvailableQuestsCallEventArgs<QuestCollection<QuestT>, QuestT>> RequestAvailableQuests
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockEventAvailableQuests );
                try
                {
                    m_EventAvailableQuests += value;
                }
                finally
                {
                    m_LockEventAvailableQuests.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockEventAvailableQuests );
                try
                {
                    m_EventAvailableQuests -= value;
                }
                finally
                {
                    m_LockEventAvailableQuests.Exit();
                }
            }
        }

        #endregion

        #endregion
    }
}
#endregion